get.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
  2. import { z } from 'zod';
  3. import { AppDataSource } from '@/server/data-source';
  4. import { UserService } from '@/server/modules/users/user.service';
  5. import { UserSchema } from '@/server/modules/users/user.entity';
  6. import { ErrorSchema } from '@/server/utils/errorHandler';
  7. import { authMiddleware } from '@/server/middleware/auth';
  8. import { AuthContext } from '@/server/types/context';
  9. import { logger } from '@/server/utils/logger';
  10. // 初始化用户服务
  11. const userService = new UserService(AppDataSource);
  12. // 路径参数Schema
  13. const GetUserParams = z.object({
  14. id: z.coerce.number().int().positive().openapi({
  15. param: { name: 'id', in: 'path' },
  16. description: '用户ID',
  17. example: 1
  18. })
  19. });
  20. // 响应Schema
  21. const GetUserResponse = z.object({
  22. code: z.number().openapi({ example: 200 }),
  23. message: z.string().openapi({ example: 'success' }),
  24. data: UserSchema
  25. });
  26. // 路由定义
  27. const routeDef = createRoute({
  28. method: 'get',
  29. path: '/{id}',
  30. middleware: [authMiddleware],
  31. request: {
  32. params: GetUserParams
  33. },
  34. responses: {
  35. 200: {
  36. description: '成功获取用户详情',
  37. content: {
  38. 'application/json': { schema: GetUserResponse }
  39. }
  40. },
  41. 400: {
  42. description: '请求参数错误',
  43. content: {
  44. 'application/json': { schema: ErrorSchema }
  45. }
  46. },
  47. 401: {
  48. description: '未授权',
  49. content: {
  50. 'application/json': { schema: ErrorSchema }
  51. }
  52. },
  53. 403: {
  54. description: '权限不足',
  55. content: {
  56. 'application/json': { schema: ErrorSchema }
  57. }
  58. },
  59. 404: {
  60. description: '用户不存在',
  61. content: {
  62. 'application/json': { schema: ErrorSchema }
  63. }
  64. },
  65. 500: {
  66. description: '服务器内部错误',
  67. content: {
  68. 'application/json': { schema: ErrorSchema }
  69. }
  70. }
  71. },
  72. tags: ['用户管理']
  73. });
  74. // 创建路由实例
  75. const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
  76. try {
  77. // 获取当前用户
  78. const currentUser = c.get('user');
  79. if (!currentUser) {
  80. logger.error('未获取到用户信息');
  81. return c.json({ code: 401, message: '未授权' }, 401);
  82. }
  83. // 获取路径参数
  84. const { id } = c.req.valid('param');
  85. // 检查权限:管理员可以查看所有用户,普通用户只能查看自己
  86. const isAdmin = await userService.isAdmin(currentUser.id);
  87. if (!isAdmin && currentUser.id !== id) {
  88. logger.error('用户 %d 权限不足,无法查看用户 %d 的详情', currentUser.id, id);
  89. return c.json({ code: 403, message: '权限不足' }, 403);
  90. }
  91. // 查询用户详情
  92. logger.api('用户 %d 查询用户 %d 详情', currentUser.id, id);
  93. const user = await userService.findOne(id);
  94. const response: z.infer<typeof GetUserResponse> = {
  95. code: 200,
  96. message: 'success',
  97. data: user
  98. };
  99. return c.json(response, 200);
  100. } catch (error) {
  101. logger.error('获取用户详情失败: %o', error);
  102. const message = error instanceof Error ? error.message : '获取用户详情失败';
  103. const statusCode = message.includes('不存在') ? 404 : 500;
  104. const errorResponse = {
  105. code: statusCode,
  106. message
  107. };
  108. return c.json(errorResponse, statusCode);
  109. }
  110. });
  111. export default app;